//
//  OpenCVTools.m
//  MinimumOpenCVLiveCamera
//
//  Created by 李雷川 on 2017/4/11.
//  Copyright © 2017年 akira108. All rights reserved.
//

#import "OpenCVTools.h"
#import <Accelerate/Accelerate.h>
using namespace cv;
using namespace std;
@implementation OpenCVTools

+(Mat)covertOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer{
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(imageBuffer, 0);
    
    uint8_t *base;
    int width, height, bytesPerRow;
    base = (uint8_t*)CVPixelBufferGetBaseAddress(imageBuffer);
    width = (int)CVPixelBufferGetWidth(imageBuffer);
    height = (int)CVPixelBufferGetHeight(imageBuffer);
    bytesPerRow = (int)CVPixelBufferGetBytesPerRow(imageBuffer);
    
    Mat mat = Mat(height, width, CV_8UC4, base);
    
    int nHeight = mat.rows;
    int nWidth  = mat.cols;
    
    cv::Point2f srcPoint[4],dstPoint[4];
    srcPoint[0].x = 0;
    srcPoint[0].y = 1;
    srcPoint[1].x = nWidth;
    srcPoint[1].y = 0;
    srcPoint[2].x = nWidth;
    srcPoint[2].y = nHeight;
    srcPoint[3].x = 0;
    srcPoint[3].y = nHeight;
    
    dstPoint[0].x = 0;
    dstPoint[0].y = nHeight*400/500;
    dstPoint[1].x = nWidth+nWidth*1/50;
    dstPoint[1].y = nHeight;
    dstPoint[2].x = nWidth+nWidth*1/50;
    dstPoint[2].y = 0;
    dstPoint[3].x = 0;
    dstPoint[3].y = nHeight*100/500;
    cv::Mat matMap = getPerspectiveTransform(srcPoint,dstPoint);
    cv::Mat img_trans = cv::Mat::zeros(nHeight,nWidth,CV_8UC4);
    warpPerspective(mat,img_trans,matMap,cv::Size(nWidth,nHeight));
    CVPixelBufferUnlockBaseAddress( imageBuffer, 0 );
    return  img_trans;

}

-(CGImageRef)cgImageRefFrom:(CMSampleBufferRef)sampleBuffer{
    
    cv::Mat cvMat = [OpenCVTools covertOutputSampleBuffer:sampleBuffer];
    NSLog(@"sampleBuffer is:%@",sampleBuffer);
    if (cvMat.elemSize() == 4) {
        cv::cvtColor(cvMat, cvMat, COLOR_BGRA2RGBA);
    }
    NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
    CGColorSpaceRef colorSpace;
    
    if (cvMat.elemSize() == 1) {
        colorSpace = CGColorSpaceCreateDeviceGray();
    } else {
        colorSpace = CGColorSpaceCreateDeviceRGB();
    }
    
    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
    
    // Creating CGImage from cv::Mat
    CGImageRef imageRef = CGImageCreate(cvMat.cols,                                 //width
                                        cvMat.rows,                                 //height
                                        8,                                          //bits per component
                                        8 * cvMat.elemSize(),                       //bits per pixel
                                        cvMat.step[0],                            //bytesPerRow
                                        colorSpace,                                 //colorspace
                                        kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
                                        provider,                                   //CGDataProviderRef
                                        NULL,                                       //decode
                                        false,                                      //should interpolate
                                        kCGRenderingIntentDefault                   //intent
                                        );
    
    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorSpace);
    return imageRef;

}
@end
